package com.itheima.service.db.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itheima.domain.db.AnalysisByDay;
import com.itheima.domain.db.Statistics;
import com.itheima.domain.vo.AnalysisSummaryVo;
import com.itheima.domain.vo.StatisticsVo;
import com.itheima.mapper.AnalysisByDayMapper;
import com.itheima.mapper.LogMapper;
import com.itheima.service.db.AnalysisByDayService;
import com.itheima.util.ComputeUtil;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;

@Service //dubbo
public class AnalysisByDayServiceImpl implements AnalysisByDayService {


    @Autowired
    LogMapper logMapper;

    @Autowired
    AnalysisByDayMapper analysisByDayMapper;


    @Override
    public void saveOrUpdate() {
        //0.注入日期字符串
        String today = DateUtil.offsetDay(new Date(), 0).toDateStr();
        String yesterday = DateUtil.offsetDay(new Date(), -1).toDateStr();

        //1.调用logmapper查询各个数据
        int numRegister = logMapper.findCountByType(today, "0102");
        int numLogin = logMapper.findCountByType(today, "0101");
        int numActive = logMapper.findActiveCount(today);
        int numRetention1Day = logMapper.findRetention1Day(today, yesterday);

        //2.查询数据库中有无当日数据
        QueryWrapper<AnalysisByDay> qw = new QueryWrapper<>();
        qw.eq("record_date", today);

        AnalysisByDay analysisByDay = analysisByDayMapper.selectOne(qw);

        if (analysisByDay == null) {
            //2.1 若无则保存
            analysisByDay = new AnalysisByDay();

            analysisByDay.setRecordDate(new Date());
            analysisByDay.setNumRegistered(numRegister);
            analysisByDay.setNumActive(numActive);
            analysisByDay.setNumLogin(numLogin);
            analysisByDay.setNumRetention1d(numRetention1Day);

            // 保存
            analysisByDayMapper.insert(analysisByDay);
        } else {
            //2.2 若有则更新
            analysisByDay.setNumRegistered(numRegister);
            analysisByDay.setNumActive(numActive);
            analysisByDay.setNumLogin(numLogin);
            analysisByDay.setNumRetention1d(numRetention1Day);

            //更新
            analysisByDayMapper.updateById(analysisByDay);
        }
    }

    @Override
    public AnalysisSummaryVo findSummary() {
        //0.准备时间的字符串
        String today = DateUtil.offsetDay(new Date(), 0).toDateStr();
        String yesterday = DateUtil.offsetDay(new Date(), -1).toDateStr();
        String passWeek = DateUtil.offsetDay(new Date(), -7).toDateStr();
        String passMonth = DateUtil.offsetDay(new Date(), -30).toDateStr();

        //1.创建AnalysisSummaryVo对象
        AnalysisSummaryVo analysisSummaryVo = new AnalysisSummaryVo();

        //2.封装对象(9个数据)
        //2.1 调用mapper的自定义查询累计用户数
        Long userSum = analysisByDayMapper.findUserSum();

        //2.2 调用mapper的自定义查询过去30天活跃人数
        Long activePassMonth = analysisByDayMapper.findCountWithinPeriod(passMonth, yesterday);

        //2.3 调用mapper的自定义查询过去7天活跃人数
        Long activePassWeek = analysisByDayMapper.findCountWithinPeriod(passWeek, yesterday);

        //2.4 查询今日分析统计对象
        QueryWrapper<AnalysisByDay> qw = new QueryWrapper<>();
        qw.eq("record_date", today);
        AnalysisByDay todaySummary = analysisByDayMapper.selectOne(qw);

        //2.5 查询昨日分析统计对象
        qw = new QueryWrapper<>();
        qw.eq("record_date", yesterday);
        AnalysisByDay yesterdaySummary = analysisByDayMapper.selectOne(qw);

        //2.6 封装9个数据
        analysisSummaryVo.setCumulativeUsers(userSum);
        analysisSummaryVo.setActivePassMonth(activePassMonth);
        analysisSummaryVo.setActivePassWeek(activePassWeek);
        analysisSummaryVo.setNewUsersToday(todaySummary.getNumRegistered().longValue());
        analysisSummaryVo.setNewUsersTodayRate(ComputeUtil.computeRate(todaySummary.getNumRegistered(), yesterdaySummary.getNumRegistered()));
        analysisSummaryVo.setLoginTimesToday(todaySummary.getNumLogin().longValue());
        analysisSummaryVo.setLoginTimesTodayRate(ComputeUtil.computeRate(todaySummary.getNumLogin(), yesterdaySummary.getNumLogin()));
        analysisSummaryVo.setActiveUsersToday(todaySummary.getNumActive().longValue());
        analysisSummaryVo.setActiveUsersTodayRate(ComputeUtil.computeRate(todaySummary.getNumActive(), yesterdaySummary.getNumActive()));

        //3.返回
        return analysisSummaryVo;
    }

    @Override
    public StatisticsVo findNewUserData(String start, String end,String lastStart,String lastEnd) {

        //调用mapper查询日期范围内‘今年’的新增用户数
        List<AnalysisByDay> thisYearDataList = analysisByDayMapper.findNewUserData(start, end);

        //调用mapper查询日期范围内‘去年’的新增用户数
        List<AnalysisByDay> lastYearDataList = analysisByDayMapper.findNewUserData(lastStart, lastEnd);

        //新建vo对象
        StatisticsVo statisticsVo = new StatisticsVo();

       //新建集合存放数据对象(今年)
        List<Object> ThisStatisticsList = new ArrayList<>();

        //新建集合存放数据对象(去年)
        List<Object> LastStatisticsList = new ArrayList<>();

        //判断查询到的集合是否为空，遍历
        if (CollUtil.isNotEmpty(thisYearDataList)) {
            for (AnalysisByDay analysisByDay : thisYearDataList) {
                //封装数据对象
                Statistics statistics = new Statistics();
                statistics.setAmount(analysisByDay.getNumRegistered());//数量
                //日期
                statistics.setTitle(DateUtil.format(analysisByDay.getRecordDate(),"yyyy-MM-dd"));
                //添加到集合中
                ThisStatisticsList.add(statistics);
            }
            //集合添加到vo中
            statisticsVo.setThisYear(ThisStatisticsList);
        }

        //判断查询到的集合是否为空，遍历
        if (CollUtil.isNotEmpty(lastYearDataList)) {
            for (AnalysisByDay analysisByDay : lastYearDataList) {
                //封装数据对象
                Statistics statistics = new Statistics();
                statistics.setAmount(analysisByDay.getNumRegistered());//数量
                //日期
                statistics.setTitle(DateUtil.format(analysisByDay.getRecordDate(),"yyyy-MM-dd"));
                //添加到集合中
                LastStatisticsList.add(statistics);
            }
            //集合添加到vo中
            statisticsVo.setLastYear(LastStatisticsList);
        }
        //返回vo对象
        return statisticsVo;
    }

    @Override
    public Object findActiveData(String start, String end,String lastStart,String lastEnd) {

        //调用mapper查询日期范围内‘今年’的活跃用户数
        List<AnalysisByDay> thisYearDataList = analysisByDayMapper.findActiveData(start, end);

        //调用mapper查询日期范围内‘去年’的活跃用户数
        List<AnalysisByDay> lastYearDataList = analysisByDayMapper.findActiveData(lastStart, lastEnd);

        //新建vo对象
        StatisticsVo statisticsVo = new StatisticsVo();

        //新建集合存放数据对象(今年)
        List<Object> ThisStatisticsList = new ArrayList<>();

        //新建集合存放数据对象(去年)
        List<Object> LastStatisticsList = new ArrayList<>();

        //判断查询到的集合是否为空，遍历
        if (CollUtil.isNotEmpty(thisYearDataList)) {
            for (AnalysisByDay analysisByDay : thisYearDataList) {
                //封装数据对象
                Statistics statistics = new Statistics();
                statistics.setAmount(analysisByDay.getNumActive());//数量
                //日期
                statistics.setTitle(DateUtil.format(analysisByDay.getRecordDate(),"yyyy-MM-dd"));
                //添加到集合中
                ThisStatisticsList.add(statistics);
            }
            //集合添加到vo中
            statisticsVo.setThisYear(ThisStatisticsList);
        }

        //判断查询到的集合是否为空，遍历
        if (CollUtil.isNotEmpty(lastYearDataList)) {
            for (AnalysisByDay analysisByDay : lastYearDataList) {
                //封装数据对象
                Statistics statistics = new Statistics();
                statistics.setAmount(analysisByDay.getNumActive());//数量
                //日期
                statistics.setTitle(DateUtil.format(analysisByDay.getRecordDate(),"yyyy-MM-dd"));
                //添加到集合中
                LastStatisticsList.add(statistics);
            }
            //集合添加到vo中
            statisticsVo.setLastYear(LastStatisticsList);
        }
        //返回vo对象
        return statisticsVo;
    }

    @Override
    public Object findNumRetention(String start, String end,String lastStart,String lastEnd) {
        //调用mapper查询日期范围内‘今年’的用户留存率
        List<AnalysisByDay> thisYearDataList = analysisByDayMapper.findNumRetention(start, end);

        //调用mapper查询日期范围内‘去年’的用户留存率
        List<AnalysisByDay> lastYearDataList = analysisByDayMapper.findNumRetention(lastStart, lastEnd);

        //新建vo对象
        StatisticsVo statisticsVo = new StatisticsVo();

        //新建集合存放数据对象(今年)
        List<Object> ThisStatisticsList = new ArrayList<>();

        //新建集合存放数据对象(去年)
        List<Object> LastStatisticsList = new ArrayList<>();

        //判断查询到的集合是否为空，遍历
        if (CollUtil.isNotEmpty(thisYearDataList)) {
            for (AnalysisByDay analysisByDay : thisYearDataList) {
                //封装数据对象
                Statistics statistics = new Statistics();
                statistics.setAmount(analysisByDay.getNumRetention1d());//数量
                //日期
                statistics.setTitle(DateUtil.format(analysisByDay.getRecordDate(),"yyyy-MM-dd"));
                //添加到集合中
                ThisStatisticsList.add(statistics);
            }
            //集合添加到vo中
            statisticsVo.setThisYear(ThisStatisticsList);
        }

        //判断查询到的集合是否为空，遍历
        if (CollUtil.isNotEmpty(lastYearDataList)) {
            for (AnalysisByDay analysisByDay : lastYearDataList) {
                //封装数据对象
                Statistics statistics = new Statistics();
                statistics.setAmount(analysisByDay.getNumRetention1d());//数量
                //日期
                statistics.setTitle(DateUtil.format(analysisByDay.getRecordDate(),"yyyy-MM-dd"));
                //添加到集合中
                LastStatisticsList.add(statistics);
                 
            }
            //集合添加到vo中
            statisticsVo.setLastYear(LastStatisticsList);
        }
        //返回vo对象
        return statisticsVo;
    }

}
